﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;

using CodeSmith.Engine;
using CodeSmith.SchemaHelper;
using SchemaExplorer;
using Configuration=CodeSmith.SchemaHelper.Configuration;

namespace CodeSmith.QuickStart
{
    public class CSLABaseTemplate : CodeTemplate
    {
        #region Constructor(s)

        public CSLABaseTemplate()
        {
            ResolveTargetLanguage();
        }

        #endregion

        #region Public Properties

        [Browsable(false)]
        public string TemplateVersion
        {
            get
            {
                var fileName = typeof(CodeSmith.SchemaHelper.Entity).Assembly.Location;
                if (fileName != null)
                {
                    return FileVersionInfo.GetVersionInfo(fileName).FileVersion;
                }

                return "3.0.0.0";
            }
        }

        private CSLAVersionEnum _cslaVersion;

        [Category("Csla Custom")]
        [Description("Csla Version")]
        [DefaultValue(CSLAVersionEnum.V384)]
        public CSLAVersionEnum CslaVersion
        {
            get
            {
                return _cslaVersion;
            }
            set
            {
                if (_cslaVersion != value)
                {
                    if (IsCSLA40 || value == CSLAVersionEnum.V384)
                    {
                        _cslaVersion = value;
                    }
                }
            }
        }

        [Browsable(false)]
        public string CSLAVersion
        {
            get
            {
                //return IsCSLA40 ? "4.0.0" : "3.8.4";
                string result = null;
                switch (CslaVersion)
                {
                    case CSLAVersionEnum.V384:
                        result = "3.8.4";
                        break;
                    case CSLAVersionEnum.V400:
                        result = "4.0.0";
                        break;
                    case CSLAVersionEnum.V422:
                        result = "4.2.2";
                        break;
                    case CSLAVersionEnum.V432:
                        result = "4.3.2";
                        break;
                }
                return result;
            }
        }

        [Browsable(false)]
        public virtual bool IsCSLA40
        {
            get
            {
                return Configuration.Instance.FrameworkVersion == FrameworkVersion.v40;
            }
        }

        [Browsable(false)]
        public string CodeSmithVersion
        {
            get
            {
                return CodeSmith.Engine.Configuration.Instance.ConfigurationVersion;
            }
        }

        [Browsable(false)]
        public string VersionInfo
        {
            get
            {
                return string.Format("CodeSmith: v{0}, CSLA Templates: v{1}, CSLA Framework: v{2}", CodeSmithVersion, TemplateVersion, CSLAVersion);
            }
        }

        #endregion

        #region Private Method(s)

        private void ResolveTargetLanguage()
        {
            if (CodeTemplateInfo != null)
            {
                if (CodeTemplateInfo.TargetLanguage.ToUpper() == "VB")
                {
                    Configuration.Instance.TargetLanguage = LanguageEnum.VB;
                }
                else
                {
                    Configuration.Instance.TargetLanguage = LanguageEnum.CSharp;
                }
            }
        }

        #endregion

        protected void RegisterCslaReferences()
        {
            //if (!Debugger.IsAttached)
            //{
            //    Debugger.Launch();
            //}
            string cslaversion = "3.8";
            switch (CslaVersion)
            {
                case CSLAVersionEnum.V400:
                    cslaversion = "4.0";
                    break;
                case CSLAVersionEnum.V422:
                    cslaversion = "4.2.2";
                    break;
                case CSLAVersionEnum.V432:
                    cslaversion = "4.3.2";
                    break;
            }

            RegisterReference(Path.GetFullPath(Path.Combine(CodeTemplateInfo.DirectoryName, string.Format(@"..\..\Common\Csla\{0}\Client\Csla.dll", cslaversion))));
        }

        #region Public Method(s)

        public virtual void RegisterReferences()
        {
            RegisterCslaReferences();
            //RegisterReference(!IsCSLA40
            //                      ? Path.GetFullPath(Path.Combine(CodeTemplateInfo.DirectoryName, @"..\..\Common\Csla\3.8\Client\Csla.dll"))
            //                      : Path.GetFullPath(Path.Combine(CodeTemplateInfo.DirectoryName, @"..\..\Common\Csla\4.0\Client\Csla.dll")));

            RegisterReference("System.Configuration");
        }

        #endregion

        #region RenderHelper

        public void RenderHelper<T>(T template) where T : EntityCodeTemplate
        {
            RenderHelper(template, false);
        }

        public void RenderHelper<T>(T template, bool renderOptionalContent) where T : EntityCodeTemplate
        {
            this.CopyPropertiesTo(template);
            template.RenderOptionalContent = renderOptionalContent;
            template.Render(this.Response);
        }

        public void RenderHelper<T>(T template, TableSchema table) where T : EntityCodeTemplate
        {
            RenderHelper(template, table, false);
        }

        public void RenderHelper<T>(T template, TableSchema table, bool renderOptionalContent) where T : EntityCodeTemplate
        {            
            this.CopyPropertiesTo(template);
            template.SourceTable = table;
            template.RenderOptionalContent = renderOptionalContent;
            template.Render(this.Response);
        }       

        #endregion
    }
}
